home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_1199 / 1117 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  6.1 KB

  1. Date: Thu, 3 Mar 94 04:55:47 PST
  2. From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
  3. Message-Id: <9403031255.AA20565@hanauma.jpl.nasa.gov>
  4. To: mint@atari.archive.umich.edu
  5. Subject: select() for BIOS serial ports
  6.  
  7. Before you get too excited, I have to warn you that this code crashes almost
  8. immediately when running MultiTOS. I've spent about 8 hours tracking it down
  9. and have gotten too frustrated, so I'm sending it out in the hopes that someone
  10. else will point out the obvious flaw....
  11.  
  12. When run without MultiTOS, it works just fine. Gory crash details to follow.
  13. First, the concept - simply build a table of pointers to the Iorec's for each
  14. serial port. At regular intervals (I originally thought of sticking this in
  15. the VBL code in intr.spp) check each head & tail pointer in each iorec, and
  16. if they're different, wake up any waiting processes. Simplicity itself. The
  17. actual check here occurs in the sleep routine, just like the checkkeys stuff
  18. works. I create a table of up to 4 entries (bios devices 6 to 9) to record
  19. the relevant pointers. (Anyone writing new device drivers for the Atari ought
  20. to do a full-blown job, like Thierry's modm0dev, so I'm not worried about
  21. supporting new bconmap'd devices...) The table contains a pointer to the input
  22. and output records of the port, and a pointer to the rsel and wsel entries in
  23. the corresponding tty struct. (There's actually space to keep all this in the
  24. tty structs themselves, if we take over some of the reserved fields, but I
  25. decided to keep things separate for now since I only want to deal with existing
  26. BIOS ttys, and not clutter up the tty struct with stuf that's not universally
  27. applicable...)
  28.  
  29. Here's the code:
  30. --- 1.2    1994/03/02 08:06:50
  31. +++ bios.c    1994/03/03 01:50:54
  32. @@ -23,4 +23,5 @@
  33.  #define AUXDEV 1
  34.  #define PRNDEV 0
  35. +#define    SERDEV 6    /* First serial port */
  36.  
  37.  /* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
  38. @@ -33,4 +34,6 @@
  39.  /* tty structures for the BIOS devices -- see biosfs.c */
  40.  extern struct tty con_tty, aux_tty, midi_tty;
  41. +extern struct bios_tty bttys[];
  42. +extern short btty_max;
  43.  
  44.  extern int tosvers;    /* from main.c */
  45. @@ -96,4 +99,27 @@
  46.  }
  47.  
  48. +void
  49. +checkbttys(void)
  50. +{
  51. +    struct bios_tty *b;
  52. +    long *l;
  53. +
  54. +    for (b=bttys;b->irec;b++) {
  55. +        if (b->irec->head != b->irec->tail) {
  56. +            wake(IO_Q, (long)b);
  57. +            l = b->rsel;
  58. +            if (*l)
  59. +                wakeselect(*l);
  60. +        }
  61. +        l = b->wsel;
  62. +        if (*l) {
  63. +            short i = b->orec->tail - b->orec->head;
  64. +            if (i < 0)
  65. +                i += b->orec->buflen;
  66. +            if (i < b->orec->hi_water)
  67. +                wakeselect(*l);
  68. +        }
  69. +    }
  70. +}
  71.  
  72.  /*
  73. @@ -181,8 +207,17 @@
  74.      }
  75.      else {
  76. -        if (dev == AUXDEV && has_bconmap)
  77. -            dev = curproc->bconmap;
  78. -
  79. -        if (dev > 0) {
  80. +        if (dev == AUXDEV) {
  81. +            if (has_bconmap) {
  82. +                dev = curproc->bconmap;
  83. +                h = dev-SERDEV;
  84. +            } else
  85. +                h = 0;
  86. +        } else
  87. +            h = dev-SERDEV;
  88. +
  89. +        if (h >= 0 && h < btty_max) {
  90. +            if (!BCONSTAT(dev))
  91. +                sleep(IO_Q, (long)&bttys[h]);
  92. +        } else if (dev > 0) {
  93.              unsigned long tick;
  94.  
  95. --- 1.4    1994/03/02 08:20:52
  96. +++ biosfs.c    1994/03/03 01:11:24
  97. @@ -147,4 +147,9 @@
  98.  };
  99.  
  100. +#define    MAX_BTTY    4    /* 4 bios_tty structs */
  101. +
  102. +struct bios_tty bttys[MAX_BTTY];
  103. +short    btty_max;
  104. +
  105.  /* Does the fcookie fc refer to the \dev\fd directory? */
  106.  #define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
  107. @@ -205,12 +210,17 @@
  108.  biosfs_init()
  109.  {
  110. -    struct bios_file *b;
  111. +    struct bios_file *b, *c;
  112.      int majdev, mindev;
  113. +    int i;
  114.  
  115.      broot = BDEV;
  116.  
  117. +    c = 0L;
  118.      for (b = broot; b->name[0]; b++) {
  119.          b->next = b+1;
  120.  
  121. +    /* Save a pointer to the first serial port */
  122. +        if (b->private == 6)
  123. +            c = b;
  124.      /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
  125.       * device 1
  126. @@ -234,4 +244,15 @@
  127.          b->next = 0;
  128.      }
  129. +    /* Initialize bios_tty structures */
  130. +    for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
  131. +        if (has_bconmap)
  132. +            Bconmap(c->private);
  133. +        bttys[i].irec = Iorec(0);
  134. +        bttys[i].orec = bttys[i].irec+1;
  135. +        bttys[i].rsel = &(c->tty->rsel);
  136. +        bttys[i].wsel = &(c->tty->wsel);
  137. +    }
  138. +    btty_max = i;
  139. +
  140.      defaultaux = new_fileptr();
  141.      defaultaux->links = 1;        /* so it never gets freed */
  142. --- 1.3    1994/03/02 08:13:00
  143. +++ proto.h    1994/03/03 00:13:14
  144. @@ -1,4 +1,5 @@
  145.  /* bios.c */
  146.  long ARGS_ON_STACK getmpb P_((void *ptr));
  147. +void checkbttys P_((void));
  148.  long bconstat P_((int dev));
  149.  long bconin P_((int dev));
  150. --- 1.3    1994/03/02 08:21:12
  151. +++ file.h    1994/03/02 23:51:16
  152. @@ -502,4 +502,11 @@
  153.  };
  154.  
  155. +struct bios_tty {
  156. +    IOREC_T        *irec;        /* From XBIOS ... */
  157. +    long        *rsel;        /* pointer to field in tty struct */
  158. +    IOREC_T        *orec;        /* Same, for output... */
  159. +    long        *wsel;
  160. +};
  161. +
  162.  /* Dcntl constants and types */
  163.  #define DEV_NEWTTY    0xde00
  164.  
  165. Here's the crash...
  166. pid  0 (MiNT): Pexec(7,27,,118A000)
  167.   ... checking for memory, creating basepage, etc.
  168.   leaving Pexec with basepage address 1194000
  169.   Pexec(106,GEM,BP:1194000,0)
  170.   Checking for memory for new PROC structure
  171.   creating environment
  172.   creating base page
  173.   exec_region
  174.   MEMORY VIOLATION: type=hardware  AA=58425249 PC=112CB54 BP=112C9CA
  175.   Operating system killed
  176.  
  177. This is a little different from my original crash; I changed a couple lines
  178. of code. The old one had AA= (um, whatever "MiNT" is in hex.). This one is
  179. "XBRI", dunno where the 'I' came from. Basically, the crash is in the
  180. checkbttys routine; the memory that btty->irec points to is no longer an
  181. Iorec. I hadn't figured on the Iorec's themselves moving around in memory
  182. after the system started, I just figured you could change the buffer pointer
  183. inside the record. Although I guess, since loading GEM.SYS means you're
  184. pretty much getting a new operating system, it can put things wherever it
  185. wants to...
  186.  
  187. The only fix I can think of right now is to compare the current contents of
  188. the Iorec pointer to the contents on the last check, and if they differ, call
  189. Bconmap and Iorec again to get the new value. 
  190.  
  191. [Bottom level details - the above crash is at the 6th instruction of
  192. checkbttys:
  193.     movel a2,sp@-
  194.     lea _bttys,a2
  195.     tstl a2@
  196.     jeq Nextloop
  197.  
  198.     movel a2@,a0
  199.     movew a0@(8),d1        <--- boom.
  200.     cmpw a0@(6),d1
  201.     ...
  202. So, it looks at a btty struct, sees that it has a non-null irec pointer,
  203. and tries to get the head index out of the Iorec struct that irec points to.
  204. But, instead of there being an Iorec there, someone has installed something
  205. else in its place... sigh.]
  206.